 
import { MoveTips } from "utils/constants/globalconstant";
import { MoveExtension } from "../move/MoveExtension";
import { BehaviorMask } from "GameLoop/WorldState/WorldConfig";
import { VisualHelper } from "utils/visual/visual";
import { UtilsHelper } from "utils/position/UtilsHelper";
import { base64table } from "../move/Kuhn-Munkres";
import { PositionHelper } from "utils/position/PositionHelper";
import { cpu_used } from "utils/decorate/decorate";

 

/**
 * 移动拓展. 分段式寻路，和跨shard 移动
 */
/*@profile*/
export default class CreepMoveExtension extends Creep
{
    nextdirection?: DirectionConstant;  // 下一次移动的位置
    moveLevel?:number;                  // 下一次移动的优先级
    private _nextPosCache?:RoomPosition;
    /**
     * 三段式移动。
     * 1.第一段确定星门
     * 2.第二段确定本shard的房间route
     * 3.第三段确定两个相邻房间的移动path
    */

    /**
     * 重写移动.分段式移动。两种模式。1 站点重用模式(省cpu,只管走啥都不管)。 2. 危险检测模式(防挨揍)
     * @param goal 目标
     * @param opt
     */
    //  @cpu_used()
    public mymoveTo(goal:{pos:RoomPosition,range:number,shard?:string},opt:IPathFinderOpt):CreepMoveReturnCode | ERR_NO_PATH | ERR_NOT_IN_RANGE | ERR_INVALID_TARGET
    {
        // this.say(`${this.nextPosition().x},${this.nextPosition().y}`);
        this.log(`info`,`移动`,JSON.stringify(goal));
        // 1.查询经过的房间路径
        // 2.获取房间路径后。每两房间查询一个站点。通过站点
        if(goal.shard )
        {
            return MoveExtension.crossshardMoveTo(this,{pos:goal.pos,range:goal.range,shard:goal.shard?goal.shard:Game.shard.name},opt) as any;
        }
        else
        {
            const msk =  this.memory.msk;
            if(goal.pos.roomName == this.pos.roomName &&
                (
                    (msk & BehaviorMask.porter)||(msk & BehaviorMask.movefill)
                )
            )
            {
                if(this.store.getUsedCapacity() ==0  )
                {
                    opt.PathCost={plainCost:1,swampCost:1}
                }
            }
            // const cpu1 = Game.cpu.getUsed()
            const code =  MoveExtension.shardMoveTo(this,goal,opt);
            // const cpu2 = Game.cpu.getUsed()
            // this.memory.Debug['move']=cpu2-cpu1
            
            
            return code as any;
        }
    }
     
    /**
     * 
     * @param direction 移动方向
     * @param level 移动指令得优先级。可以是其他爬施加得影响。也可以是自己主动要移动得优先级
     * @returns 
     */
    public move(direction: DirectionConstant | Creep,level:number=0): any
    {
        let tmpDir:DirectionConstant
        if(typeof direction =="number" )
        {
            tmpDir = direction;
        }
        else
        {
            tmpDir = this.pos.getDirectionTo(direction);
        }
        const pos = this.pos;
        const _move_intents = global._move_intents[this.room.name] ?? (global._move_intents[this.room.name] = {})
        const pos_str = base64table[pos.x] + base64table[pos.y];
        _move_intents[pos_str] = {id: this.id, step: [tmpDir],p:this.crossLevel()}
        return OK;
        // if(this.fatigue)
        // {
        //     return ERR_TIRED
        // }
        // let tmpDir:DirectionConstant
        // if(typeof direction =="number" )
        // {
        //     tmpDir = direction;
        // }
        // else
        // {
        //     tmpDir = this.pos.getDirectionTo(direction);
        // }
        // this._move(tmpDir)
        
    }
    public flee( arg:IMoveGoal[], opt:IPathFinderOpt ): void
    {
        return MoveExtension.flee(this,arg,opt);
    }
    public printNextDirection()
    {
        if(this.nextdirection)
        {
            this.say(`${MoveTips[this.nextdirection]}`)
        }
        else 
        {
            this.say('0');
        }
    }
    public nextPosition()
    {
        if(this._nextPosCache)
        {
            return this._nextPosCache
        }
        else 
        {
            const path = this.memory._move?.path;
            if(path)
            {
                const pathstep = Room.deserializePath(path);
                if(pathstep.length)
                {
                    this._nextPosCache = PositionHelper.Create({x: pathstep[0].x,y: pathstep[0].y,roomName: this.room.name});
                    return this._nextPosCache
                }
            }
            this._nextPosCache = this.pos
        }
        
        return this.pos
    }
}
 